
Function.prototype.bind = Function.prototype.bind || function(oThis){

	/*var args = Array.prototype.slice.call(arguments,1)
		func = this;

	return function(){
		this.apply(oThis,Array.prototype.slice.call(arguments).concat(args));
	}*/

	if(typeof this !== "function"){
		throw new TypeError("Function");
	}

	var args = Array.prototype.slice.call(arguments,1),fToBind = this,
		fNOP = function(){},
		fBound = function(){
			return fToBind.apply(this instanceof fNOP && oThis ? this : oThis || window,
				args.concat(Array.prototype.slice.call(arguments)))
		};

	fNOP.prototype = this.prototype;
	fBound.prototype = new fNOP;

	return fBound;
}


var obj = {name:"test"};
var name = "window";
function test(arg1,arg2){
	console.log(arg1,arg2,this.name);
}

test.bind(obj,1111)(2222);


Function.prototype.bind = function(oThis){
	var args = Array.prototype.slice.call(arguments,1),
	func = this,
	nop = function(){},
	fBound = function(){
		return func.apply(this instanceof nop && oThis ? this : oThis || window,
			args.concat(Array.prototype.slice.call(arguments)));
	}


	nop.prototype = this.prototype;
	fBound.prototype = new nop;

	return fBound;
}

var obj = {name:"test"};
var name = "window";
function test(arg1,arg2){
	console.log(arg1,arg2,this.name);
}

test.bind(obj,1111)(2222);



function deepCopy(data){
	let result;

	if(Array.isArray(data)){
		result = [];
	}
	else if(typeof data  == "object"){
		result = {}
	}
	else {
		return data;
	}

	if(Array.isArray(data)){
		for(let i=0,len=data.length;i<len;i++){
			result[i] = deepCopy(data[i]);
		}
	}
	else if(typeof data  == "object"){
		for(let k in data){
			result[k] = deepCopy(data[k]);
		}
	}

	return result;
}

var o1 = {name:"111",arr:[1,2,3,4],obj:{name:"111111"}},o2 = deepCopy(o1);
console.log(o1,o2);


Object.prototype.clone = function(){
	var result = this.constructor === "Array" ? []:{};

	for(var i in this){
		result[i] = typeof this[i] === "object" ? this[i].clone():this[i];
	}
}